/*
*DSC图示有层次结构的2D图，所以相对于slide的操作就有4个操作，分别为up,down,left,right
*（ 我们把当前的slide 称作 current）
* up 操作，找到current的super，如果没有则不会产生效果，注意不是找坐标在其上方的
* down 操作：找到current的第一个sub，如果没有则不会产生效果，注意同上
* right 操作：找到同一个序列中的下一个slide，如果没有，则找下一个并行的slide
* left 操作： 与right相反。
*
* 实现的时候给每个图元对象增加了一个band 属性，该属性为图元所在band的Y坐标
* 在这里将一个composite 看做是一个branch，参数中的branch就是这个意思
*/
//这里相当于import 临时使用 最后必须删掉
slideOp = _dss_editor._canvas._operation.slideOp;

slideOp.next = 0;
slideOp.pre = 1;
slideOp.up = 2;
slideOp.down = 3;
slideOp.bandHeight = labelHeight;
slideOp.isViewed = [];
slideOp.fire = function(eventObj) {
	try {
		switch (eventObj.eventType) {
			case MOUSE_L_DOWN:
				return this.handleMouseDown(eventObj);
				break;
			case MOUSE_R_DOWN:
				return this.handleMouseDown(eventObj);
				break;
			case KEY_LEFT:
				return this.handlePre(eventObj);
			case KEY_RIGHT:
				return this.handleNext(eventObj);
			case KEY_UP:
				return this.handleUp(eventObj);
			case KEY_DOWN:
				return this.handleDown(eventObj);
			case KEY_SPACE:
				return this.handleAuto(eventObj);
			default:
				break;
		}
	} catch (exc) {
		console.error(exc.stack);
	}
};
slideOp.handleMouseDown = function(eventObj) {
	// var canvas = eventObj.canvas;	
	// var current = _dss_editor._toolkit.findSystemByLocation(canvas.sys.getChildren(), eventObj.location, canvas);
	this.isViewed = [];
};
slideOp.handlePre = function(eventObj) {
	var slide = this.getCurrent(eventObj);
	if(slide.style === STYLE_ROOT){
		return false;
	}
	var pre = this.getPre(slide);
	if (pre) {
		this.isViewed.push(pre);
		this.gotoSlide(eventObj, pre);
		return true;
	}
	return false;
};
slideOp.handleNext = function(eventObj) {
	var current = this.getCurrent(eventObj);
	var next = this.getNext(current);
	if (next) {
		this.isViewed.push(next);
		this.gotoSlide(eventObj, next);
		return true;
	}
	return false;
};
slideOp.handleUp = function(eventObj) {
	var current = this.getCurrent(eventObj);
	if (current.isDrilling || current == eventObj.canvas.sys) {
		eventObj.canvas.drillUp();
	} else {
		var up = this.getUp(current);
		// if (up && up.getType() === COMMENT) {
		// up = this.getNext(up);
		// }
		if (up) {
			if (up.isDrilling) {
				eventObj.canvas.drillUp();
			}
			this.isViewed.push(up);
			this.gotoSlide(eventObj, up);
			return true;
		}
	}
	return false;
};
slideOp.handleDown = function(eventObj) {
	var current = this.getCurrent(eventObj);
	if (current && current.style != STYLE_ROOT && !current.isShowContent()) {
		eventObj.canvas.drillDown();
	}
	var down = this.getDown(current);
	// if (down && down.getType() === COMMENT) {
	// down = this.getNext(down);
	// }
	if (down) {
		this.isViewed.push(down);
		this.gotoSlide(eventObj, down);
		return true;
	}
	return false;
};
slideOp.handleAuto = function(eventObj) {
	//console.log(slideOp.viewed);
	var current = this.getCurrent(eventObj);
	var auto = this.getAutoNext(current);
	if (auto && auto.getType() === COMMENT) {
		auto = this.getAutoNext(auto);
	}
	var done;
	if (current.style === SYSTEM && !current.isShowContent()) {
		eventObj.canvas.drillDown();
		if (current.getValue() != '') {
			return;
		}
	}

	if (auto && auto != current) {
		this.isViewed.push(auto);
		this.gotoSlide(eventObj, auto);
		return true;
	}
	return false;
};
slideOp.getCurrent = function(eventObj) {
	var canvas = eventObj.canvas;
	if (eventObj.current) {
		return eventObj.current;
	} else if (canvas.selectionDiagrams.length > 0) {
		return canvas.selectionDiagrams[0];
	} else {
		return canvas.sys;
	}
};
slideOp.gotoSlide = function(eventObj, slide) {
	var canvas = eventObj.canvas;
	//	delete this.getCurrent(eventObj).band;
	console.log(slide.name);
	_dss_editor._toolkit.gotoSystem(slide, canvas);
};
slideOp.getPre = function(slide) {
	var pre;
	if (slide) {
		if (slide.getLinkTo() && slide.getLinkTo().length > 0 && slide.getLinkTo()[0].linkType === TYPE_TRANSITION) {
			pre = slide.getLinkTo()[0].fromSystem;
		} else {
			pre = this.getPreSeq(slide);
		}
	}
	if (pre && pre.getType() === COMMENT) {
		pre = this.getPre(down);
	}
	return pre;
};
/*
 * 得到下一个slide。
 * 首先根据 branch order查找，然后根据 band order查找
 */
slideOp.getNext = function(slide) {
	var next;
	if (slide && slide.style != STYLE_ROOT) {
		// if (slide.getLinkFrom() && slide.getLinkFrom().length > 0 && slide.getLinkFrom()[0].linkType === TYPE_TRANSITION && slide.getLinkFrom()[0].toSystem != slide) {
		// next = slide.getLinkFrom()[0].toSystem;
		// }else{
		// next = this.getNextSeq(slide);
		// }
		next = this.getNextInSeq(slide);
		if (!next) {
			next = this.getNextSeq(slide);
		}
		if (next && next.getType() === COMMENT) {
			next = this.getNext(next);
		}
		return next;
	}

};
slideOp.getUp = function(slide) {
	//var slide = this.getCurrent(eventObj);
	if (slide && slide.parent && slide.parent.style != STYLE_ROOT) {
		return slide.parent;
	}
};
slideOp.getDown = function(slide) {
	var down = this.getPreR(slide);
	//var pre_r = this.getPreR(slide);
	if (!down) {
		down = this.getFirstSeq(slide);
	}
	if (down && down.getType() === COMMENT) {
		down = this.getNext(down);
	}
	return down;
};
slideOp.getAutoNext = function(slide) {
	var down = this.getDown(slide);
	var up = this.getUp(slide);
	var next = this.getNext(slide);
	if (down) {
		return down;
	} else if (next) {
		return next;
	} else if (up) {
		var upNext;
		while (!upNext && up) {
			upNext = this.getNext(up);
			up = this.getUp(up);
		}
		return upNext;
	}

};
//返回的是seq的第一个元素
slideOp.getSeqs = function(branch) {
	var seqs = [];
	if (branch.getSystemComplexity() > 1) {
		for (var i in branch.getChildren()) {
			var sub = branch.getChildren()[i];
			if (sub.getType() === COMMENT) {
				continue;
			}
			var isSeq = true;
			if (sub) {
				if (sub.getLinkTo()) {
					for (var i = 0; i < sub.getLinkTo().length; i++) {
						var link = sub.getLinkTo()[i];
						if (link.linkType === TYPE_TRANSITION && link.fromSystem != sub) {
							isSeq = false;
						}
					};
				}
				if (isSeq) {
					seqs.push(sub);
				}
			}
		}
	}
	return seqs;
};

slideOp.getNextSeq = function(slide) {
	var seqFirst = this.getSeqFirstSlide(slide);
	var seqs = this.getSeqs(seqFirst.parent);
	var next = this.getNextInBand(seqFirst, seqs);
	var post_r = this.getPostR(slide.parent);
	//null;
	if (slide === post_r) {
		return;
	}

	if (!next) {
		var currentBand = this.getCurrentBand(seqFirst, seqs);
		var nextBand = this.getNextBand(currentBand, seqs);
		next = this.getBandFirst(nextBand, seqs);
	}
	if (next === post_r) {
		next = this.getNextInBand(next, seqs);
	}
	if (!next && post_r) {
		next = post_r;
	}
	return next;
};
slideOp.getPreSeq = function(slide) {
	var seqFirst = this.getSeqFirstSlide(slide);
	var seqs = this.getSeqs(seqFirst.parent);
	var pre = this.getPreInBand(seqFirst, seqs);
	var pre_r = this.getPreR(slide.parent);
	if (slide === pre_r) {
		return;
	}
	if (!pre) {
		var currentBand = this.getCurrentBand(seqFirst, seqs);
		var preBand = this.getPreBand(currentBand, seqs);
		pre = this.getBandLast(preBand, seqs);
		if (this.getCurrentBand(pre, seqs) === currentBand) {
			pre = null;
		}
	}
	if (pre && pre.name === 'pre_r') {
		pre = this.getPreInBand(pre, seqs);
	}
	if (!pre && pre_r) {
		pre = pre_r;
	}
	// console.log('pre name:' + pre.name);
	return pre;
};

/*
 * 找到一个composite 中的第一个，也就是第一个 band的第一个序列的第一个slide
 */
slideOp.getFirstSeq = function(branch) {
	var seqs = this.getSeqs(branch);
	var first = this.getBandFirst(0, seqs);
	return first;
};
//找到名字为pre_r的图元，该图元需要第一个执行，不需要计算位置
slideOp.getPreR = function(branch) {
	var seqs = this.getSeqs(branch);
	for (var i = 0; i < seqs.length; i++) {
		var seq = seqs[i];
		if (seq.name === 'pre_r') {
			return seq;
		}
	}
};

//找到名字为pre_r的图元，该图元需要第一个执行，不需要计算位置
slideOp.getPostR = function(branch) {
	var seqs = this.getSeqs(branch);
	for (var i = 0; i < seqs.length; i++) {
		var seq = seqs[i];
		if (seq.name === 'post_r') {
			return seq;
		}
	}
};

slideOp.getSeqFirstSlide = function(slide) {
	var first = null;
	while (slide) {
		first = slide;
		if (slide) {
			if(slide.style === LINK){
				slide = slide.fromSystem;
			}else if (slide.getLinkTo() && slide.getLinkTo().length > 0 && slide.getLinkTo()[0].linkType === TYPE_TRANSITION && slide.getLinkTo()[0].fromSystem != slide) {
				slide = slide.getLinkTo()[0].fromSystem;
			} else {
				break;
			}
		}
	}
	return first;
};
slideOp.openSlide = function(content) {
	var sysForView = JSON.parse(content);
	var canvas = buildTab(sysForView.presenterName, CANVAS_VIEWSLIDES);
	canvas.init(sysForView);
	canvas.matchSize();
	canvas.update();
};
/*
 * 参数band 为 下一个band的顶层坐标，用于查找相对该坐标最顶层的图元
 * 也就是说当找到最接近该坐标的SEQ之后，band坐标会变成该图元的坐标
 */
slideOp.getBandFirst = function(band, seqs) {
	//var seqs = this.getSeqs(branch);
	var topmost = this.getBandTopmost(band, seqs);
	var first;
	if (topmost) {
		band = this.getSlideRealBounds(topmost).y;
		var bandSeqs = this.getBandSeqs(band, seqs);
		for (var i = 0; i < bandSeqs.length; i++) {
			var seq = bandSeqs[i];
			if (!first || this.getSlideRealBounds(first).x > this.getSlideRealBounds(seq).x) {
				first = seq;
			}
		}
	}
	return first;
};
slideOp.getBandLast = function(band, seqs) {
	//var seqs = this.getSeqs(branch);
	var topmost = this.getBandTopmost(band, seqs);
	var last;
	if (topmost) {
		band = this.getSlideRealBounds(topmost).y;
		var bandSeqs = this.getBandSeqs(band, seqs);
		for (var i = 0; i < bandSeqs.length; i++) {
			var seq = bandSeqs[i];
			if (!last || this.getSlideRealBounds(last).x < this.getSlideRealBounds(seq).x) {
				last = seq;
			}
		}
	}
	return last;
};
/*
 * 找到该band内所有的slides,这里的band的top已经是该band内最顶层图元的坐标了，以下皆同
 */
slideOp.getBandSeqs = function(band, seqs) {
	var bandSeqs = [];
	for (var i = 0; i < seqs.length; i++) {
		var seq = seqs[i];
		if (this.getSlideRealBounds(seq).y >= band && this.getSlideRealBounds(seq).y < band + this.bandHeight) {
			//seq.band = band;
			bandSeqs.push(seq);
		}
	}
	return bandSeqs;
};
/*
 * 查找上一个band，找到与该band （待考虑）
 */
slideOp.getPreBand = function(curBand, seqs) {
	var band = 0;
	var preBand = 0;
	var bandSeqs = [];
	if(curBand < this.bandHeight){
		return curBand;
	}
	while (band < curBand) {
		preBand = band;
		band = this.getNextBand(band, seqs);
		var topmost = this.getBandTopmost(band, seqs);
		// if (!topmost) {
		// break;
		// }
		band = this.getSlideRealBounds(topmost).y;

	}
	return preBand;
};
/*
 * 查找下一个band，首先找到该band内bottom的坐标最小的，
 * 如果该最小坐标小于 band的高度，那么以band高度+band顶坐标的为准
 */
slideOp.getNextBand = function(band, seqs) {
	var bandSeqs = this.getBandSeqs(band, seqs);
	var newBand = band;
	for (var i = 0; i < bandSeqs.length; i++) {
		var seq = bandSeqs[i];
		if (newBand === band || newBand > this.getSlideRealBounds(seq).y + this.bandHeight) {
			newBand = this.getSlideRealBounds(seq).y + this.bandHeight;
		}
	}
	return newBand;
};
/*
 * 找到该slide 在所在band内的左边最靠近该slide的slide
 * 如果该slide不是seq的首图 则忽略，band信息在该slide中
 */
slideOp.getNextInBand = function(curSeq, seqs) {
	var bandSeqs = this.getBandSeqs(this.getCurrentBand(curSeq, seqs), seqs);
	var next;
	for (var i = 0; i < bandSeqs.length; i++) {
		var bandSeq = bandSeqs[i];
		if (bandSeq.name === 'pre_r') {
			continue;
		}
		if (this.getSlideRealBounds(bandSeq).x > this.getSlideRealBounds(curSeq).x) {
			if (!next || this.getSlideRealBounds(bandSeq).x < this.getSlideRealBounds(next).x) {
				next = bandSeq;
			}
		} else if (this.getSlideRealBounds(bandSeq).x === this.getSlideRealBounds(curSeq).x && this.getSlideRealBounds(bandSeq).y > this.getSlideRealBounds(curSeq).y) {
			next = bandSeq;
			break;
		}
	}
	return next;
};
/*
 * 找到该slide 在所在band内的右边最靠近该slide的slide
 */
slideOp.getPreInBand = function(curSeq, seqs) {
	var bandSeqs = this.getBandSeqs(this.getCurrentBand(curSeq, seqs), seqs);
	var pre;
	for (var i = 0; i < bandSeqs.length; i++) {
		var bandSeq = bandSeqs[i];
		if (bandSeq.name === 'pre_r') {
			continue;
		}
		if (this.getSlideRealBounds(bandSeq).x < this.getSlideRealBounds(curSeq).x) {
			if (!pre || this.getSlideRealBounds(bandSeq).x > this.getSlideRealBounds(pre).x) {
				pre = bandSeq;
			}
		} else if (this.getSlideRealBounds(bandSeq).x === this.getSlideRealBounds(curSeq).x && this.getSlideRealBounds(bandSeq).y < this.getSlideRealBounds(curSeq).y) {
			pre = bandSeq;
			break;
		}
	}
	return pre;
};
slideOp.getBandTopmost = function(band, seqs) {
	var topmost;
	for (var i = 0; i < seqs.length; i++) {
		var seq = seqs[i];
		var seqBounds = this.getSlideRealBounds(seq);
		if (seqBounds.y >= band) {
			if (!topmost || this.getSlideRealBounds(topmost).y - band > seqBounds.y - band) {
				topmost = seq;
			}
		}
	}
	return topmost;
};
slideOp.getCurrentBand = function(seq, seqs) {
	var band = 0;
	var bandSeqs = [];
	do {
		var topmost = this.getBandTopmost(band, seqs);
		if (!topmost) {
			break;
		}
		band = this.getSlideRealBounds(topmost).y;
		bandSeqs = this.getBandSeqs(band, seqs);
		if ($.inArray(seq,bandSeqs) !== -1) {
			return band;
		}
		band = this.getNextBand(band, seqs);
	} while(true);
};
slideOp.getSlideRealBounds = function(slide) {
	if (slide.style === POINT) {
		return slide.showInfo;
	} else {
		return slide.showInfo.rectangle;
	}
};
/* 得到在顺时针方向上branch与root之间的角度 
 * branch 其实指的是branch的第一个图元
 */
slideOp.getBranchAngle = function(root,branch){
	var rootRect = this.getSlideRealBounds(root);
	var branchRect = this.getSlideRealBounds(branch);
	var rootCenter = {x:(rootRect.x + rootRect.w)/2,y:(rootRect.y + rootRect.h)/2};
	var branchCenter = {x:(branchRect.x + branchRect.w)/2,y:(branchRect.y + branchRect.h)/2};
	var angle = Math.atan2(branchCenter.y - rootCenter.y,branchCenter.x - rootCenter.x);
	console.log(branch.name +':'+angle);
	return angle;	
};
/*
 * 得到最靠近的分支
 * root为根slide
 */
slideOp.getNearestBranch = function(root) {
	var nearest;
	var nearAngle = Math.PI * 2;
	var links = this.getFromTrans(root);
	for (var i = 0; i < links.length; i++) {
		var link = links[i];
		var angle = this.getBranchAngle(root,link.getToSystem());
		//这里需要判断图中有循环的情况，如果其中一条分支已经浏览过则继续找
		 if (angle < nearAngle) {
			nearest = link.getToSystem();
			nearAngle = angle;
		}
	}
	return nearest;
};
/*
 * 得到下一个的分支
 * root为根slide
 * curBranchLink 为当前branch的迁移线
 */
slideOp.getNextBranch = function(root, curBranchLink) {
	var next;
	var curAngle =  this.getBranchAngle(root,curBranchLink.getToSystem());
	var nearAngle = Math.PI * 2;
	var links = this.getFromTrans(curBranchLink);
	if(links.length === 0){
		links = this.getFromTrans(root);
	}	
	for (var i = 0; i < links.length; i++) {
		var link = links[i];
		var angle = this.getBranchAngle(root,link.getToSystem());
		if (angle > curAngle && angle < nearAngle) {
			next = link.getToSystem();
			nearAngle = angle;
		}
	}
	return next;
};

slideOp.getNextInSeq = function(cur) {
	var fromTrans = this.getFromTrans(cur);
	var next;
	if (fromTrans.length === 1) {
		next = fromTrans[0].getToSystem();
	} else if (fromTrans.length > 1) {
		next = this.getNearestBranch(cur);
		this.isViewed.push(next);//表明这条分支已经浏览过，下回再执行到这时好进行判断
	} else if(cur.style === SYSTEM){
		var rootInfo = this.getCurBranchRootInfo(cur);
		if (rootInfo.root != null) {
			next = this.getNextBranch(rootInfo.root, rootInfo.curLink);
			if(!next){
				rootInfo = this.getCurBranchRootInfo(rootInfo.root);
				if(rootInfo.root && rootInfo.curLink){
					next = this.getNextBranch(rootInfo.root,rootInfo.curLink);
				}				
			}
		}
	}
	return next;
};

/*
 * 这个方式是获取 root 和当前已经执行的link
 */
slideOp.getCurBranchRootInfo = function(cur) {
	var rootInfo = {
		root : null,
		curLink : null
	};
	if(cur.style === LINK){
		cur = cur.getFromSystem();
	}
	var toTrans = this.getToTrans(cur);
	if (toTrans.length === 1) {
		rootInfo.root = toTrans[0].getFromSystem();
		rootInfo.curLink = toTrans[0];
	} else if (toTrans.length > 1) {
		//这个地方还没想清楚如何处理 暂时和一条线时做相同的处理
		rootInfo.root = toTrans[0].getFromSystem();
		rootInfo.curLink = toTrans[0];
	}
	if (rootInfo.root && this.getFromTrans(rootInfo.root).length === 1 && this.getFromTrans(rootInfo.curLink).length === 0) {
		var pre = this.getCurBranchRootInfo(rootInfo.root);
		if (pre != null) {
			rootInfo = pre;
		}
	}
	return rootInfo;
};

slideOp.getFromTrans = function(diagram) {
	var links = diagram.linkFrom;
	var fromTrans = [];
	if (links) {
		for (var i = 0; i < links.length; i++) {
			var link = links[i];
			if (link.linkType === TYPE_TRANSITION) {
				fromTrans.push(link);
			}
		}
	}
	return fromTrans;
};
slideOp.getToTrans = function(slide) {
	var links = slide.getLinkTo();
	var toTrans = [];
	if (links) {
		for (var i = 0; i < links.length; i++) {
			var link = links[i];
			if (link.linkType === TYPE_TRANSITION) {
				toTrans.push(link);
			}
		}
	}
	return toTrans;
};
delete slideOp;
